﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ScriptEngine.Interface;
using Microsoft.Scripting.Hosting;
using Microsoft.ApplicationServer.Caching;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Serialization;
using Microsoft.Scripting;

namespace ScriptEngine
{
    [DataContract]
    public class ObjectWrapper<T>
        where T : class
    {
        [DataMember]
        private byte[] binaries;
        
        public T Value
        {
            get
            {
                return Deserialize(binaries);
            }
            set
            {
                binaries = Serialize(value);
            }
        }
        private byte[] Serialize(T o)
        {
            BinaryFormatter bf = new BinaryFormatter();

            using (MemoryStream ms = new MemoryStream())
            {
                bf.Serialize(ms, o);

                return ms.ToArray();
            }
        }
        private T Deserialize(byte[] b) 
        {
            BinaryFormatter bf = new BinaryFormatter();

            using (MemoryStream ms = new MemoryStream())
            {
                ms.Read(b, 0, b.Length);

                ms.Position = 0;

                return (T)bf.Deserialize(ms);
            }
        }
    }

    public class AppFabricScriptCache : IScriptCache
    {
        DataCache cache = new DataCacheFactory().GetCache("default");

        public CompiledCode this[string script]
        {
            get
            {
                ObjectWrapper<CompiledCode> wrapper = cache.Get(script) as ObjectWrapper<CompiledCode>;

                if (wrapper != null)
                    return wrapper.Value;
                else
                    return null;
            }
            set
            {
                if (cache.Get(script) == null)
                {
                    cache.Add(script, new ObjectWrapper<CompiledCode>{ Value = value });
                }
                else
                {
                    cache.Put(script, new ObjectWrapper<CompiledCode> { Value = value });
                }

            }
        }
    }
}
